package br.edu.ufcg.ccc.javalog.view;

import java.util.Scanner;

import br.edu.ufcg.ccc.javalog.Address;
import br.edu.ufcg.ccc.javalog.Franchise;
import br.edu.ufcg.ccc.javalog.exceptions.BadAddressException;
import br.edu.ufcg.ccc.javalog.exceptions.StoreException;

/**
 * Common methods utilized by text views.
 * @author Victor Freire
 *
 */
public class ViewUtil {
	private static final Scanner sc = new Scanner(System.in);
	
	/**
	 * Get integer that is between the requested interval([a,b]) from the standard input.
	 * @param prompt request message
	 * @param min minimum value (inclusive)
	 * @param max max value(inclusive)
	 * @return valid integer
	 */
	public static int getInt(String prompt, int min, int max) {
		while(true) {
			System.out.printf(prompt);
			while(!sc.hasNextInt()) sc.next();
						
			int inteiro = sc.nextInt();
			if(min <= inteiro && inteiro <= max) return inteiro;
			System.err.printf("Numero invalido! Precisa estar entre %d e %d.%n", min, max);
		}
	}
	
	/**
	 * Gets a valid string from the user.
	 * @param prompt request message
	 * @return valid and non-empty string
	 */
	public static String getString(String prompt) {
		System.out.printf(prompt);
		while(true) {
			
			while(!sc.hasNextLine()) sc.next();
			
			String txt = sc.nextLine();
			
			if(txt == null) {
				System.err.println("Texto invalido!");
				System.out.printf(prompt);
			}
			else if(txt.equals("")) continue;
			else return txt;
		}
	}
	
	/**
	 * Gets a boolean answer from the the standard input.
	 * @return boolean answer
	 */
	public static boolean getYesOrNo(String prompt) {
		final String answersPositive = "y;yes;sim;s;";
		final String answersNegative = "n;no;nao;nao;";
		while(true) {
			String answer = getString(prompt);
			
			if(answersPositive.contains(answer + ";")) return true;
			else if(answersNegative.contains(answer + ";")) return false;
			
			System.err.println("Resposta invalida! Use s, n, sim ou nao.");
		}
	}
	
	/**
	 * Gets a valid address from the standard input.
	 * @return valid address 
	 */
	public static Address getAddress() {
		while(true) {
			String region = getString("Regiao: ");
			String state = getString("Estado: ");
			String city = getString("Cidade: ");
			String district = getString("Bairro: ");
			String zipcode = getString("CEP: ");
			String street = getString("Endereco: ");
			String number = getString("Numero: ");
			try {
				return new Address(region, state, city, district, zipcode, street, number);
			}
			catch(BadAddressException e) {
				System.err.println("Endereco invalido!");
			}
		}
	}
	
	/**
	 * Gets a valid Franchise from the standard input.
	 * @return valid Franchise
	 */
	public static Franchise getFranchise() {
		while(true) {
			String name = getString("Nome: ");
			Address address = getAddress();
			boolean hasAirport = getYesOrNo("Tem aeroporto?(s/n): ");
			
			try {
				return new Franchise(name, address, hasAirport);
			} catch(StoreException ex) {
				assert false : "não devia chegar aqui";
				System.err.println("Erro: Dados inválidos! Por favor tente novamente.*");
			}
		}
	}
}
